package com.misty.auth.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.misty.auth.component.LoginUser;
import com.misty.auth.service.AuthService;
import com.misty.common.Util.JwtUtil;
import com.misty.common.Util.RedisCache;
import com.misty.common.Util.SecurityUtil;
import com.misty.common.bean.Result;
import com.misty.common.constants.RedisKey;
import com.misty.common.param.LoginParam;
import com.misty.dao.domain.Users;
import com.misty.dao.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cthulhu
 * @since 2022-11-21
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Resource
    private UsersMapper usersMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

     /**
      * @param
      * @return
      * @Description  登录
      * @Date 2023/1/9 9:15
      */
     @Override
    public Result<?> login(LoginParam param){
        // 生成一个包含账号密码的认证信息
        Authentication authenticationtoken = new UsernamePasswordAuthenticationToken(param.getUsername(), param.getPassword());
        // AuthenticationManager校验这个认证信息，返回一个已认证的Authentication
        Authentication authentication = authenticationManager.authenticate(authenticationtoken);

        if(Objects.isNull(authentication)){
            throw new RuntimeException("登录失败");
        }
        // 将返回的Authentication存到上下文中
        SecurityContextHolder.getContext().setAuthentication(authentication);

        //临时user对象
        //使用userid生成token
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        //authenticate存入redis

        redisCache.setCacheObject("login_"+userId,loginUser);
        redisCache.clearCache(RedisKey.BLOG_DETAIL);

        String photo = getUserphoto(userId);

        //响应数据
        HashMap<String,String> hashMap = new HashMap<>();
        hashMap.put("token",jwt);
        hashMap.put("username",loginUser.getUser().getUsername());
        hashMap.put("userId",userId);
        hashMap.put("photo",photo);

        return Result.success(0,"登录成功!",hashMap);
    }

    private String getUserphoto(String userId) {
        Users users = usersMapper.selectById(userId);
        return users.getAvatar();
    }

    /**
      * @param
      * @return
      * @Description 注册
      * @Date 2023/1/9 9:15
      */
     @Override
    public Result<?> register(Users user) {
        Users user2 = usersMapper.selectOne(
                Wrappers.<Users>lambdaQuery()
                        .eq(Users::getUsername, user.getUsername())
        );
        if (user2 != null) {
            return Result.error(-1, "用户名不能重复");
        }
        if (user.getPassword() == null) {
            String encode_temp = bCryptPasswordEncoder.encode("123456");
            user.setPassword(encode_temp);
        }
        String encode_password = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encode_password);
        int insert = usersMapper.insert(user);
        if (insert != 0) {
            QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username",user.getUsername());
            Users user1 = usersMapper.selectOne(queryWrapper);
            usersMapper.insertRoleIdWithUserId(user1.getId(),4);
            return Result.success();
        } else {
            return Result.error();
        }
    }

     /**
      * @param	null
      * @return
      * @Description 注销
      * @Date 2023/1/9 9:17
      */
     @Override
    public Result<?> changePassword(Users user) {
        if (!SecurityUtil.judgeLogin()) {
            return Result.error("请先登录！");
        }
        //校验参数
        if(StrUtil.isEmpty(user.getPassword()) ){
            return Result.error("修改密码不能为空!");
        }
        //获取用户
        LoginUser loginUser = (LoginUser) SecurityUtil.getPrincipal();
        Integer userId = loginUser.getUser().getId();
        user.setId(userId);
        //加密
        String encodePassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        int update = usersMapper.updateById(user);
        if(update <= 0){
            return Result.error("修改密码失败!");
        }
//        // 发送邮件
//        Users users = usersMapper.selectById(userId);
//        /* 暂时方案，后面用mq发邮箱  */
//        if(StrUtil.isNotEmpty(users.getEmail())){
//            emailService.sendRegisterMail(users.getEmail(),"修改密码","密码修改成功!");
//        }
         Map<String, Object> map = new HashMap<>();
         map.put("userId",userId);
         return Result.success("修改密码成功",map);
    }

      /**
       * @param
       * @return
       * @Description
       * @Date 2023/1/9 9:17
       */
      @Override
     public Result<?> logout() {
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
         Integer userid = loginUser.getUser().getId();
         redisCache.deleteObject("login_" + userid);
         redisCache.clearCache(RedisKey.BLOG_DETAIL);
         return Result.success(0,"注销成功！");
     }

}
